﻿using mozhi.smarterp.Finance.Banks;
using mozhi.smarterp.Finance.Banks.Repository;
using mozhi.smarterp.Finance.DataDicts;
using mozhi.smarterp.Finance.DataDicts.Repository;
using mozhi.smarterp.Finance.Enums;
using mozhi.smarterp.Finance.Logs;
using mozhi.smarterp.Finance.Logs.Repository;
using Mozhi.Abp.Domain.BasicData.Repositories;
using System.Collections.Generic;
using System.Threading.Tasks;
using Volo.Abp.Data;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Guids;
using Volo.Abp.MultiTenancy;

namespace mozhi.smarterp.Finance.DataSeeder
{
    public class FinanceDataSeedContributor : IDataSeedContributor, ITransientDependency
    {
        private IGuidGenerator _guidGenerator;
        private IOrganizationRepository _organizationRepository;
        private ICurrencyRepository _currencyRepository;
        private IBankTypeRepository _bankTypeRepository;
        private IOperationLogSettingRepository _operationLogSettingRepository;
        private IDataDictionaryRepository _dataDictionaryRepository;
        private readonly ICurrentTenant _currentTenant;

        public FinanceDataSeedContributor(IOrganizationRepository organizationRepository, IOperationLogSettingRepository operationLogSettingRepository,
            IGuidGenerator guidGenerator, ICurrencyRepository currencyRepository, IBankTypeRepository bankTypeRepository , IDataDictionaryRepository dataDictionaryRepository,
            ICurrentTenant currentTenant)
        {
            _guidGenerator = guidGenerator;
            _organizationRepository = organizationRepository;
            _currencyRepository = currencyRepository;
            _bankTypeRepository = bankTypeRepository;
            _operationLogSettingRepository = operationLogSettingRepository;
            _dataDictionaryRepository = dataDictionaryRepository;
            _currentTenant = currentTenant;
        }

        public async Task SeedAsync(DataSeedContext context)
        {
            using (_currentTenant.Change(context?.TenantId))
            {
                await SeedOrganizationDataAsync(context);
                await SeedCurrencyDataAsync(context);
                await SeedBankTypeDataAsync(context);
                await SeedOperationLogSettingDataAsync(context);
                await SeedDictionaryDataAsync(context);
            }
        }

        #region
        private async Task SeedOrganizationDataAsync(DataSeedContext context)
        {
            //var count = await _organizationRepository.CountAsync();

            //if (count == 0)
            //{
            //    var defaultOrganization = new Organization(_guidGenerator.Create(), "Mozhi finance system", "Mozhi finance system", "", default, null, null);

            //    await _organizationRepository.CreateAsync(defaultOrganization);
            //}
        }

        private async Task SeedCurrencyDataAsync(DataSeedContext context)
        {
            //var currencyCount = await _currencyRepository.GetCountAsync();

            //if (currencyCount == 0)
            //{

            //    var defaultCurrencys = new List<Currency>() {
            //        new Currency(_guidGenerator.Create(), "CNY", "人民币","¥" , true) ,
            //        new Currency(_guidGenerator.Create(), "USD", "美元","$", true) ,
            //        new Currency(_guidGenerator.Create(), "EUR", "欧元","€", true) ,
            //        new Currency(_guidGenerator.Create(), "AUD", "澳元","A$", true) ,
            //        new Currency(_guidGenerator.Create(), "JPY", "日元","¥", true) ,
            //        new Currency(_guidGenerator.Create(), "CAD", "加元","C$", true)
            //    };

            //    await _currencyRepository.CreateAsync(defaultCurrencys);
            //}
        }

        private async Task SeedBankTypeDataAsync(DataSeedContext context)
        {
            var bankTypeCount = await _bankTypeRepository.GetCountAsync();

            if (bankTypeCount == 0)
            {
                var defaultBankTypes = new List<BankType>()
                {
                    new BankType(_guidGenerator.Create() , "中国银行"),
                   new BankType(_guidGenerator.Create() , "中国建设银行"),
                   new BankType(_guidGenerator.Create() , "中国农业银行"),
                   new BankType(_guidGenerator.Create() , "中国工商银行"),
                   new BankType(_guidGenerator.Create() , "中国平安银行"),
                   new BankType(_guidGenerator.Create() , "浦发银行"),
                   new BankType(_guidGenerator.Create() , "中国招商银行")
                };

                foreach (var bankTyep in defaultBankTypes)
                {
                    await _bankTypeRepository.InsertAsync(bankTyep);
                }
            }
        }

        private async Task SeedOperationLogSettingDataAsync(DataSeedContext context)
        {
            var matchLogSetting = await _operationLogSettingRepository.FindAsync(ModuleCodeType.JournalNumberPrefix);

            if (matchLogSetting == null)
            {
                //凭证前缀
                var journalNumberPrefixLogSetting = new OperationLogSetting(_guidGenerator.Create(), ModuleCodeType.JournalNumberPrefix, "凭证字", null);

                var journalNumberPrefixLogSettingItems = new List<OperationSettingItem>
                {
                    new OperationSettingItem(_guidGenerator.Create(), journalNumberPrefixLogSetting.Id, "Code", "编码",0),
                    new OperationSettingItem(_guidGenerator.Create(), journalNumberPrefixLogSetting.Id, "Name", "名称", 0),
                    new OperationSettingItem(_guidGenerator.Create(), journalNumberPrefixLogSetting.Id, "IsDefault", "是否默认",0),
                };

                journalNumberPrefixLogSetting.ChangeItems(journalNumberPrefixLogSettingItems);

                await _operationLogSettingRepository.InsertAsync(journalNumberPrefixLogSetting);
            }

            matchLogSetting = await _operationLogSettingRepository.FindAsync(ModuleCodeType.PrintTemplate);

            if (matchLogSetting == null)
            {
                var logSetting = new OperationLogSetting(_guidGenerator.Create(), ModuleCodeType.PrintTemplate, "打印模板", null);

                var logSettingItems = new List<OperationSettingItem>
                {
                    new OperationSettingItem(_guidGenerator.Create(), logSetting.Id, "Name", "名称", 0),
                    new OperationSettingItem(_guidGenerator.Create(), logSetting.Id, "ModuleCode", "模块", 0),
                    new OperationSettingItem(_guidGenerator.Create(), logSetting.Id, "TemplateFileId", "文件",4),
                };

                logSetting.ChangeItems(logSettingItems);

                await _operationLogSettingRepository.InsertAsync(logSetting);
            }

            matchLogSetting = await _operationLogSettingRepository.FindAsync(ModuleCodeType.Organization);

            if (matchLogSetting == null)
            {
                var logSetting = new OperationLogSetting(_guidGenerator.Create(), ModuleCodeType.Organization, "组织", null);

                var logSettingItems = new List<OperationSettingItem>
                {
                    new OperationSettingItem(_guidGenerator.Create(), logSetting.Id, "Name", "名称", 0),
                    new OperationSettingItem(_guidGenerator.Create(), logSetting.Id, "LegalName", "法定名称", 0),
                    new OperationSettingItem(_guidGenerator.Create(), logSetting.Id, "AccountingStandard", "会计准则", 5),
                    new OperationSettingItem(_guidGenerator.Create(), logSetting.Id, "ActivationDate", "启用日期",0),
                    new OperationSettingItem(_guidGenerator.Create(), logSetting.Id, "CurrencyId", "货币",6),
                    new OperationSettingItem(_guidGenerator.Create(), logSetting.Id, "TaxIDNumber", "税号",0),
                };

                logSetting.ChangeItems(logSettingItems);

                await _operationLogSettingRepository.InsertAsync(logSetting);
            }

            matchLogSetting = await _operationLogSettingRepository.FindAsync(ModuleCodeType.Currency);

            if (matchLogSetting == null)
            {
                var logSetting = new OperationLogSetting(_guidGenerator.Create(), ModuleCodeType.Currency, "货币", null);

                var logSettingItems = new List<OperationSettingItem>
                {
                    new OperationSettingItem(_guidGenerator.Create(), logSetting.Id, "Name", "名称", 0),
                    new OperationSettingItem(_guidGenerator.Create(), logSetting.Id, "Code", "编码", 0),
                    new OperationSettingItem(_guidGenerator.Create(), logSetting.Id, "Symbol", "符号", 0),
                    new OperationSettingItem(_guidGenerator.Create(), logSetting.Id, "Activated", "激活", 0)
                };

                logSetting.ChangeItems(logSettingItems);

                await _operationLogSettingRepository.InsertAsync(logSetting);
            }

            matchLogSetting = await _operationLogSettingRepository.FindAsync(ModuleCodeType.Customer);

            if (matchLogSetting == null)
            {
                var logSetting = new OperationLogSetting(_guidGenerator.Create(), ModuleCodeType.Customer, "客户", null);

                var logSettingItems = new List<OperationSettingItem>
                {
                    new OperationSettingItem(_guidGenerator.Create(), logSetting.Id, "Name", "名称", 0),
                    new OperationSettingItem(_guidGenerator.Create(), logSetting.Id, "Code", "编码", 0),
                    new OperationSettingItem(_guidGenerator.Create(), logSetting.Id, "ReceivableAccountId", "应收科目", 3),
                    new OperationSettingItem(_guidGenerator.Create(), logSetting.Id, "PrereceiveAccountId", "预收科目", 3),
                    new OperationSettingItem(_guidGenerator.Create(), logSetting.Id, "Activated", "激活", 0)
                };

                logSetting.ChangeItems(logSettingItems);

                await _operationLogSettingRepository.InsertAsync(logSetting);
            }

            matchLogSetting = await _operationLogSettingRepository.FindAsync(ModuleCodeType.Supplier);

            if (matchLogSetting == null)
            {
                var logSetting = new OperationLogSetting(_guidGenerator.Create(), ModuleCodeType.Supplier, "供应商", null);

                var logSettingItems = new List<OperationSettingItem>
                {
                    new OperationSettingItem(_guidGenerator.Create(), logSetting.Id, "Code", "编码",0),
                    new OperationSettingItem(_guidGenerator.Create(), logSetting.Id, "Name", "名称", 0),
                    new OperationSettingItem(_guidGenerator.Create(), logSetting.Id, "PayableAccountId", "应付科目",3),
                    new OperationSettingItem(_guidGenerator.Create(), logSetting.Id, "PrepaymentAccountId", "预付科目", 3),
                    new OperationSettingItem(_guidGenerator.Create(), logSetting.Id, "Activated", "激活", 0)
                };

                logSetting.ChangeItems(logSettingItems);

                await _operationLogSettingRepository.InsertAsync(logSetting);
            }

            matchLogSetting = await _operationLogSettingRepository.FindAsync(ModuleCodeType.Thirdparty);

            if (matchLogSetting == null)
            {
                var logSetting = new OperationLogSetting(_guidGenerator.Create(), ModuleCodeType.Thirdparty, "第三方", null);

                var logSettingItems = new List<OperationSettingItem>
                {
                    new OperationSettingItem(_guidGenerator.Create(), logSetting.Id, "Code", "编码",0),
                    new OperationSettingItem(_guidGenerator.Create(), logSetting.Id, "Name", "名称", 0),
                    new OperationSettingItem(_guidGenerator.Create(), logSetting.Id, "CurrentAccountId", "往来科目",3),
                    new OperationSettingItem(_guidGenerator.Create(), logSetting.Id, "Activated", "激活", 0)
                };

                logSetting.ChangeItems(logSettingItems);

                await _operationLogSettingRepository.InsertAsync(logSetting);
            }
        }

        private async Task SeedDictionaryDataAsync(DataSeedContext context)
        {
            var dictionaryCount = await _dataDictionaryRepository.GetCountAsync(new Querys.DataDictPageQuery() { ModuleCode = ModuleCodeType.AccountType});

            if (dictionaryCount == 0)
            {
                var dictionaries = new List<DataDictionary>()
                {
                   new DataDictionary(_guidGenerator.Create() , ModuleCodeType.AccountType , "10" , "资产"),
                   new DataDictionary(_guidGenerator.Create() , ModuleCodeType.AccountType , "11" , "流动资产"),
                   new DataDictionary(_guidGenerator.Create() , ModuleCodeType.AccountType , "12" , "非流动资产"),
                   new DataDictionary(_guidGenerator.Create() , ModuleCodeType.AccountType , "20" , "负债"),
                   new DataDictionary(_guidGenerator.Create() , ModuleCodeType.AccountType , "21" , "流动负债"),
                   new DataDictionary(_guidGenerator.Create() , ModuleCodeType.AccountType , "22" , "非流动负债"),
                   new DataDictionary(_guidGenerator.Create() , ModuleCodeType.AccountType , "30" , "共同"),
                   new DataDictionary(_guidGenerator.Create() , ModuleCodeType.AccountType , "40" , "权益"),
                   new DataDictionary(_guidGenerator.Create() , ModuleCodeType.AccountType , "41" , "所有者权益"),
                   new DataDictionary(_guidGenerator.Create() , ModuleCodeType.AccountType , "42" , "以前年度损益调整"),
                   new DataDictionary(_guidGenerator.Create() , ModuleCodeType.AccountType , "50" , "成本"),
                   new DataDictionary(_guidGenerator.Create() , ModuleCodeType.AccountType , "51" , "成本"),
                   new DataDictionary(_guidGenerator.Create() , ModuleCodeType.AccountType , "52" , "营业成本及税金"),
                   new DataDictionary(_guidGenerator.Create() , ModuleCodeType.AccountType , "53" , "其他损失"),
                   new DataDictionary(_guidGenerator.Create() , ModuleCodeType.AccountType , "54" , "期间费用"),
                   new DataDictionary(_guidGenerator.Create() , ModuleCodeType.AccountType , "55" , "所得税"),
                   new DataDictionary(_guidGenerator.Create() , ModuleCodeType.AccountType , "60" , "收益"),
                   new DataDictionary(_guidGenerator.Create() , ModuleCodeType.AccountType , "61" , "营业收入"),
                   new DataDictionary(_guidGenerator.Create() , ModuleCodeType.AccountType , "62" , "其他收益")
                };

                foreach (var dictionary in dictionaries)
                {
                    await _dataDictionaryRepository.InsertAsync(dictionary);
                }
            }
        }
        #endregion
    }
}
